#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <string>
#include <map>
#include <vector>
#include <fstream>
#include <sstream>

/**
 * 配置管理测试类
 * 测试配置文件解析、管理和验证功能
 */
class ConfigurationManagementTest : public ::testing::Test {
protected:
    void SetUp() override {
        // 测试环境初始化
        test_config_dir_ = "/tmp/wondertrader_test_config/";
        // 创建测试配置目录（如果不存在）
        system(("mkdir -p " + test_config_dir_).c_str());
    }

    void TearDown() override {
        // 清理测试配置文件
        system(("rm -rf " + test_config_dir_).c_str());
    }

    std::string test_config_dir_;
};

/**
 * 简单的配置管理器实现用于测试
 */
class SimpleConfigManager {
public:
    // 从字符串加载配置
    bool load_from_string(const std::string& config_content) {
        config_map_.clear();
        std::istringstream iss(config_content);
        std::string line;
        
        while (std::getline(iss, line)) {
            // 跳过空行和注释
            if (line.empty() || line[0] == '#') {
                continue;
            }
            
            // 解析键值对
            size_t pos = line.find('=');
            if (pos != std::string::npos) {
                std::string key = line.substr(0, pos);
                std::string value = line.substr(pos + 1);
                
                // 去除前后空格
                key = trim(key);
                value = trim(value);
                
                config_map_[key] = value;
            }
        }
        
        return true;
    }
    
    // 从文件加载配置
    bool load_from_file(const std::string& filename) {
        std::ifstream file(filename);
        if (!file.is_open()) {
            return false;
        }
        
        std::string content((std::istreambuf_iterator<char>(file)),
                           std::istreambuf_iterator<char>());
        file.close();
        
        return load_from_string(content);
    }
    
    // 保存配置到文件
    bool save_to_file(const std::string& filename) const {
        std::ofstream file(filename);
        if (!file.is_open()) {
            return false;
        }
        
        for (const auto& pair : config_map_) {
            file << pair.first << "=" << pair.second << std::endl;
        }
        
        file.close();
        return true;
    }
    
    // 获取字符串值
    std::string get_string(const std::string& key, const std::string& default_value = "") const {
        auto it = config_map_.find(key);
        return (it != config_map_.end()) ? it->second : default_value;
    }
    
    // 获取整数值
    int get_int(const std::string& key, int default_value = 0) const {
        std::string value = get_string(key);
        if (value.empty()) {
            return default_value;
        }
        
        try {
            return std::stoi(value);
        } catch (...) {
            return default_value;
        }
    }
    
    // 获取浮点数值
    double get_double(const std::string& key, double default_value = 0.0) const {
        std::string value = get_string(key);
        if (value.empty()) {
            return default_value;
        }
        
        try {
            return std::stod(value);
        } catch (...) {
            return default_value;
        }
    }
    
    // 获取布尔值
    bool get_bool(const std::string& key, bool default_value = false) const {
        std::string value = get_string(key);
        if (value.empty()) {
            return default_value;
        }
        
        // 转换为小写
        std::string lower_value = value;
        std::transform(lower_value.begin(), lower_value.end(), lower_value.begin(), ::tolower);
        
        return (lower_value == "true" || lower_value == "1" || lower_value == "yes");
    }
    
    // 设置值
    void set_string(const std::string& key, const std::string& value) {
        config_map_[key] = value;
    }
    
    void set_int(const std::string& key, int value) {
        config_map_[key] = std::to_string(value);
    }
    
    void set_double(const std::string& key, double value) {
        config_map_[key] = std::to_string(value);
    }
    
    void set_bool(const std::string& key, bool value) {
        config_map_[key] = value ? "true" : "false";
    }
    
    // 检查键是否存在
    bool has_key(const std::string& key) const {
        return config_map_.find(key) != config_map_.end();
    }
    
    // 获取所有键
    std::vector<std::string> get_all_keys() const {
        std::vector<std::string> keys;
        for (const auto& pair : config_map_) {
            keys.push_back(pair.first);
        }
        return keys;
    }
    
    // 清空配置
    void clear() {
        config_map_.clear();
    }
    
    // 获取配置项数量
    size_t size() const {
        return config_map_.size();
    }

private:
    std::map<std::string, std::string> config_map_;
    
    // 去除字符串前后空格
    std::string trim(const std::string& str) const {
        size_t start = str.find_first_not_of(" \t\r\n");
        if (start == std::string::npos) {
            return "";
        }
        
        size_t end = str.find_last_not_of(" \t\r\n");
        return str.substr(start, end - start + 1);
    }
};

/**
 * 测试基本配置解析
 */
TEST_F(ConfigurationManagementTest, TestBasicConfigParsing) {
    SimpleConfigManager config;
    
    std::string config_content = R"(
# 这是注释
server_host=localhost
server_port=8080
debug_mode=true
max_connections=100
timeout=30.5

# 另一个注释
database_url=mysql://localhost:3306/wondertrader
)";
    
    EXPECT_TRUE(config.load_from_string(config_content));
    
    // 验证字符串值
    EXPECT_EQ(config.get_string("server_host"), "localhost");
    EXPECT_EQ(config.get_string("database_url"), "mysql://localhost:3306/wondertrader");
    
    // 验证整数值
    EXPECT_EQ(config.get_int("server_port"), 8080);
    EXPECT_EQ(config.get_int("max_connections"), 100);
    
    // 验证浮点数值
    EXPECT_DOUBLE_EQ(config.get_double("timeout"), 30.5);
    
    // 验证布尔值
    EXPECT_TRUE(config.get_bool("debug_mode"));
    
    // 验证不存在的键
    EXPECT_EQ(config.get_string("nonexistent_key", "default"), "default");
    EXPECT_EQ(config.get_int("nonexistent_key", 42), 42);
    EXPECT_DOUBLE_EQ(config.get_double("nonexistent_key", 3.14), 3.14);
    EXPECT_FALSE(config.get_bool("nonexistent_key", false));
}

/**
 * 测试配置文件读写
 */
TEST_F(ConfigurationManagementTest, TestConfigFileIO) {
    SimpleConfigManager config;
    
    // 设置一些配置值
    config.set_string("app_name", "WonderTrader");
    config.set_int("version_major", 1);
    config.set_int("version_minor", 0);
    config.set_double("price_precision", 0.01);
    config.set_bool("enable_logging", true);
    
    // 保存到文件
    std::string config_file = test_config_dir_ + "test_config.ini";
    EXPECT_TRUE(config.save_to_file(config_file));
    
    // 从文件加载到新的配置管理器
    SimpleConfigManager config2;
    EXPECT_TRUE(config2.load_from_file(config_file));
    
    // 验证加载的配置
    EXPECT_EQ(config2.get_string("app_name"), "WonderTrader");
    EXPECT_EQ(config2.get_int("version_major"), 1);
    EXPECT_EQ(config2.get_int("version_minor"), 0);
    EXPECT_DOUBLE_EQ(config2.get_double("price_precision"), 0.01);
    EXPECT_TRUE(config2.get_bool("enable_logging"));
}

/**
 * 测试配置验证
 */
TEST_F(ConfigurationManagementTest, TestConfigValidation) {
    SimpleConfigManager config;
    
    // 测试有效配置
    std::string valid_config = R"(
server_port=8080
max_connections=1000
timeout=60.0
debug_mode=false
)";
    
    EXPECT_TRUE(config.load_from_string(valid_config));
    
    // 验证配置的有效性
    auto validate_config = [&config]() -> std::vector<std::string> {
        std::vector<std::string> errors;
        
        // 验证端口范围
        int port = config.get_int("server_port", 0);
        if (port <= 0 || port > 65535) {
            errors.push_back("无效的服务器端口: " + std::to_string(port));
        }
        
        // 验证最大连接数
        int max_conn = config.get_int("max_connections", 0);
        if (max_conn <= 0 || max_conn > 10000) {
            errors.push_back("无效的最大连接数: " + std::to_string(max_conn));
        }
        
        // 验证超时时间
        double timeout = config.get_double("timeout", 0.0);
        if (timeout <= 0.0 || timeout > 3600.0) {
            errors.push_back("无效的超时时间: " + std::to_string(timeout));
        }
        
        return errors;
    };
    
    // 验证有效配置
    auto errors = validate_config();
    EXPECT_TRUE(errors.empty());
    
    // 测试无效配置
    std::string invalid_config = R"(
server_port=70000
max_connections=-1
timeout=0
)";
    
    config.clear();
    EXPECT_TRUE(config.load_from_string(invalid_config));
    
    errors = validate_config();
    EXPECT_FALSE(errors.empty());
    EXPECT_GE(errors.size(), 3); // 应该有3个错误
}

/**
 * 测试配置层次结构
 */
TEST_F(ConfigurationManagementTest, TestConfigHierarchy) {
    // 模拟配置层次结构：默认配置 -> 用户配置 -> 命令行参数
    
    // 默认配置
    SimpleConfigManager default_config;
    default_config.set_string("server_host", "0.0.0.0");
    default_config.set_int("server_port", 8080);
    default_config.set_bool("debug_mode", false);
    default_config.set_int("log_level", 2);
    
    // 用户配置
    SimpleConfigManager user_config;
    user_config.set_string("server_host", "localhost"); // 覆盖默认值
    user_config.set_bool("debug_mode", true); // 覆盖默认值
    // server_port 和 log_level 使用默认值
    
    // 命令行参数
    SimpleConfigManager cmdline_config;
    cmdline_config.set_int("server_port", 9090); // 覆盖默认值和用户配置
    // 其他值使用用户配置或默认配置
    
    // 合并配置的函数
    auto merge_configs = [](const SimpleConfigManager& base, 
                           const SimpleConfigManager& override) -> SimpleConfigManager {
        SimpleConfigManager merged = base;
        
        for (const std::string& key : override.get_all_keys()) {
            merged.set_string(key, override.get_string(key));
        }
        
        return merged;
    };
    
    // 按优先级合并配置
    SimpleConfigManager final_config = merge_configs(default_config, user_config);
    final_config = merge_configs(final_config, cmdline_config);
    
    // 验证最终配置
    EXPECT_EQ(final_config.get_string("server_host"), "localhost"); // 来自用户配置
    EXPECT_EQ(final_config.get_int("server_port"), 9090); // 来自命令行参数
    EXPECT_TRUE(final_config.get_bool("debug_mode")); // 来自用户配置
    EXPECT_EQ(final_config.get_int("log_level"), 2); // 来自默认配置
}

/**
 * 测试配置热重载
 */
TEST_F(ConfigurationManagementTest, TestConfigHotReload) {
    std::string config_file = test_config_dir_ + "hot_reload_config.ini";
    
    // 创建初始配置文件
    {
        std::ofstream file(config_file);
        file << "refresh_interval=1000\n";
        file << "max_retries=3\n";
        file << "enable_cache=true\n";
        file.close();
    }
    
    SimpleConfigManager config;
    EXPECT_TRUE(config.load_from_file(config_file));
    
    // 验证初始配置
    EXPECT_EQ(config.get_int("refresh_interval"), 1000);
    EXPECT_EQ(config.get_int("max_retries"), 3);
    EXPECT_TRUE(config.get_bool("enable_cache"));
    
    // 修改配置文件
    {
        std::ofstream file(config_file);
        file << "refresh_interval=2000\n"; // 修改值
        file << "max_retries=5\n"; // 修改值
        file << "enable_cache=false\n"; // 修改值
        file << "new_option=hello\n"; // 新增值
        file.close();
    }
    
    // 重新加载配置
    EXPECT_TRUE(config.load_from_file(config_file));
    
    // 验证更新后的配置
    EXPECT_EQ(config.get_int("refresh_interval"), 2000);
    EXPECT_EQ(config.get_int("max_retries"), 5);
    EXPECT_FALSE(config.get_bool("enable_cache"));
    EXPECT_EQ(config.get_string("new_option"), "hello");
}

/**
 * 测试配置错误处理
 */
TEST_F(ConfigurationManagementTest, TestConfigErrorHandling) {
    SimpleConfigManager config;
    
    // 测试加载不存在的文件
    EXPECT_FALSE(config.load_from_file("/nonexistent/path/config.ini"));
    
    // 测试格式错误的配置
    std::string malformed_config = R"(
valid_key=valid_value
invalid_line_without_equals
another_valid_key=another_value
=value_without_key
key_without_value=
)";
    
    // 应该能够加载，但会跳过格式错误的行
    EXPECT_TRUE(config.load_from_string(malformed_config));
    
    // 验证有效的配置项被正确加载
    EXPECT_EQ(config.get_string("valid_key"), "valid_value");
    EXPECT_EQ(config.get_string("another_valid_key"), "another_value");
    EXPECT_EQ(config.get_string("key_without_value"), ""); // 空值
    
    // 验证无效的配置项不存在
    EXPECT_FALSE(config.has_key("invalid_line_without_equals"));
    
    // 测试类型转换错误
    config.set_string("invalid_int", "not_a_number");
    config.set_string("invalid_double", "not_a_double");
    config.set_string("invalid_bool", "maybe");
    
    // 应该返回默认值
    EXPECT_EQ(config.get_int("invalid_int", 42), 42);
    EXPECT_DOUBLE_EQ(config.get_double("invalid_double", 3.14), 3.14);
    EXPECT_FALSE(config.get_bool("invalid_bool", false));
}

/**
 * 测试配置性能
 */
TEST_F(ConfigurationManagementTest, TestConfigPerformance) {
    SimpleConfigManager config;
    
    // 创建大量配置项
    const int NUM_CONFIG_ITEMS = 10000;
    
    auto start = std::chrono::high_resolution_clock::now();
    
    for (int i = 0; i < NUM_CONFIG_ITEMS; ++i) {
        config.set_string("key_" + std::to_string(i), "value_" + std::to_string(i));
        config.set_int("int_key_" + std::to_string(i), i);
        config.set_double("double_key_" + std::to_string(i), i * 1.5);
        config.set_bool("bool_key_" + std::to_string(i), i % 2 == 0);
    }
    
    auto end = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    
    // 设置配置应该很快
    EXPECT_LT(duration.count(), 1000); // 应该在1秒内完成
    
    // 验证配置项数量
    EXPECT_EQ(config.size(), NUM_CONFIG_ITEMS * 4);
    
    // 测试查找性能
    start = std::chrono::high_resolution_clock::now();
    
    for (int i = 0; i < 1000; ++i) {
        int index = i % NUM_CONFIG_ITEMS;
        EXPECT_EQ(config.get_string("key_" + std::to_string(index)), 
                 "value_" + std::to_string(index));
        EXPECT_EQ(config.get_int("int_key_" + std::to_string(index)), index);
        EXPECT_DOUBLE_EQ(config.get_double("double_key_" + std::to_string(index)), 
                        index * 1.5);
        EXPECT_EQ(config.get_bool("bool_key_" + std::to_string(index)), 
                 index % 2 == 0);
    }
    
    end = std::chrono::high_resolution_clock::now();
    duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
    
    // 查找配置应该很快
    EXPECT_LT(duration.count(), 100); // 应该在100毫秒内完成
}
